(()->

  orgSync = $bb.sync;
  getUrl = (object)->
    if not(object and object.url)
      return null
    return if _.isFunction object.url then object.url() else object.url

  methodMap = 
    'create': 'POST'
    'update': 'PUT'
    'delete': 'DELETE'
    'read':   'GET'

  create_uuid = ()->
    S4 = ()->
       (((1+Math.random())*0x10000)|0).toString(16).substring(1)
    (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4())

  #backbone extend
  $bb.sync = (method, model, options)->
    uuid = $.user_id()
    user_id = '2'
    data = options.data or model.data
    options.data = _.extend {uuid: uuid, userid: user_id, windowname: window['windowname']}, data
    success = options.success
    options.success = (resp, status, xhr)->
      model.trigger 'finish:sync', model, method, model, resp, status, xhr, options
      if success
        success resp, status, xhr

    model.trigger 'start:sync', model, method, model, options
    if not options.url
      options.url = getUrl model
    if window['api_base']
      options.url = window['api_base'] + options.url
      
    $.ajax _.extend options, 
      type: methodMap[method]
      dataType: 'json'
      windowname: window['windowname']

  _.extend $, {
    carts: ()->
      if window['carts'] is undefined
        window['carts'] = new $colls.Goods
        window['carts'].fetch()
      return window['carts']
    user_id: ()->
      uuid = $.cookie 'uuid'
      if uuid is null
        uuid = create_uuid()
        $.cookie 'uuid', uuid, {expires: 40000}
      return uuid
    cookie : (name, value, options={})->
        if typeof value != 'undefined'
          if value is null
            value = ''
            options.expires = -1
          expires = ''
          if options.expires and (typeof options.expires == 'number' or options.expires.toUTCString)
            if typeof options.expires == 'number'
                date = new Date()
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000))
            else
                date = options.expires
            expires = '; expires=' + date.toUTCString()
          path = if options.path then '; path=' + (options.path) else ''
          domain = if options.domain then '; domain=' + (options.domain) else ''
          secure = if options.secure then '; secure' else ''
          document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join ''
        else
          cookieValue = null
          if document.cookie and document.cookie != ''
            cookies = document.cookie.split ';'
            for cookie in cookies
              cookie = cookie.replace( /^\s\s*/, "" ).replace( /\s\s*$/, "" )
              if cookie.substring(0, name.length + 1) == (name + '=')
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1))
                  break
          cookieValue
    czero: (m)-> 
      if m < 10 then '0' + m else m
    fdate: (d)->
      [d.getFullYear(), $.czero(d.getMonth()+1), $.czero(d.getDate())].join('')
    week: (d)->
      ['日', '一', '二', '三', '四', '五', '六'][d.getDay()]
    pdate: (d)->
      d = String d
      new Date Number(d[0..3]), Number(d[4..5])-1, Number(d[6..])
    download: (game)->
      window.location.href = game.get 'download_url'
    trac_download: (gid, from="bar")->
      $.ajax 
        url: window['api_base'] + '/record/trac'
        data:
          from: from, to: 'download', game_id: gid, uuid: $.user_id(), windowname: true
        type: 'GET'
        dataType: 'json'
        windowname: true
        success: ()->
      true
  }
  
).call @